package apis

import (
	"github.com/gin-gonic/gin"
	"hulk-api/models"
	"net/http"
	"fmt"
	"strconv"
	"hulk-api/models/cicd"
	"hulk-api/models/k8s"
)


func GetDeploymentTemplatePath(c *gin.Context) {
	var tem k8s.TemplatePath
	tem.Name = c.Query("name")
	fmt.Println("path name is .. ." , tem.Name)
	paths,err := tem.GetPath()
	if err != nil {
		fmt.Println("error is",err)
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"path": paths,
	})

}


func AddDeployItem(c *gin.Context) {
	var item cicd.Deployment
	c.BindJSON(&item)
	err := item.Create()
	if err != nil {
		//defer item.delete()
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func AddDeployView(c *gin.Context) {
	var view cicd.View
	c.BindJSON(&view)
	err := view.Create()
	if err != nil {
		//defer item.delete()
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func SaveDeployView(c *gin.Context) {
	var view cicd.View
	c.BindJSON(&view)
	err := view.Save()
	if err != nil {
		//defer item.delete()
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func DeleteDeployView(c *gin.Context) {
	var view cicd.View
	c.BindJSON(&view)
	err := view.Delete()
	if err != nil {
		//defer item.delete()
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}


func SaveConfig(c *gin.Context) {
	var item cicd.Deployment
	c.BindJSON(&item)
	err := item.Save()
	if err != nil {
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func GetDeployItems(c *gin.Context) {
	var item cicd.Deployment
	//c.BindJSON(&item)
	items,_ := item.GetDeployItems()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"items": items,
	})
}

func GetDeployViews(c *gin.Context) {
	var view cicd.View
	//c.BindJSON(&item)
	views,_ := view.GetDeployViews()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"views": views,
	})
}
func GetDeployView(c *gin.Context) {
	var view cicd.View
	//c.BindJSON(&item)
	view.Name = c.Query("name")
	_ = view.GetDeployView()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"view": view,
	})
}

func GetDeployViewItems(c *gin.Context) {
	var view cicd.View
	//c.BindJSON(&item)
	view.Name = c.Query("name")
	items,_ := view.GetDeployItems()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"items": items,
	})
}


func GetDeployItem(c *gin.Context) {
	var item cicd.Deployment
	//c.BindJSON(&item)
	item.Name = c.Query("name")
	fmt.Println(item.Name)
	_ = item.GetDeployItem()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"item": item,
	})
}

func StartDeploy(c *gin.Context) {
	var item cicd.Deployment
	c.BindJSON(&item)
	runing,err := item.IsRuning()
	if err != nil {
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	if runing {
		fmt.Println("debug new ......")
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": "该项目正在构建中，请稍后......",
		})
		return
	}

	fmt.Println("begin test for pool run ")
	//cicd.DeployDispatch.JobQueue <- item
	err = cicd.DeployDispatch.AddJob(item)
	if err != nil {
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}

	//item.Start()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func GetWorkspace(c *gin.Context) {
	var item models.DeplaymentItem
	//c.BindJSON(&item)
	item.Name = c.Query("item")
	dirStruct,_ := item.LoadWorkspace()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"dirStruct": dirStruct,
	})
}

func GetOutput(c *gin.Context) {
	var item cicd.Deployment
	//c.BindJSON(&item)
	item.Name = c.Query("item")
	//var outputList []util.Output
	outputList,_ := item.LoadOutput()


	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"outputList": outputList,
	})
}


func DeleteDeployItem(c *gin.Context) {
	var item models.DeplaymentItem
	c.BindJSON(&item)
	err := item.Delete()
	if err != nil {
		fmt.Println("create ansibe deployment error : " , err.Error())
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func CleanWorkspace(c *gin.Context) {
	var item models.DeplaymentItem
	c.BindJSON(&item)
	err := item.Clean()
	if err != nil {
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func GetDeployTaskProgress(c *gin.Context) {
	var item cicd.Deployment

	result,visible , _ := item.Progress()
	fmt.Println(result)
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"progressResult": result,
		"visible": visible,

	})
}

func GetDeployTaskQueue(c *gin.Context) {
	queues := cicd.GetDeployQueues()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"queues":queues,
	})
}

func UpdateDeployConcurrency(c *gin.Context) {
	maxWorker := c.Query("max")
	maxNumber,_ := strconv.Atoi(maxWorker)
	if maxNumber == cicd.DeployDispatch.MaxWorkers {
		c.JSON(http.StatusOK,gin.H{
			"code": 200,
		})
		return
	}
	cicd.RestartWithMaxWorker(maxNumber)
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}
func GetDeployConcurrency(c *gin.Context) {
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"max" : cicd.DeployDispatch.MaxWorkers,
	})
}

//部署任务
//func AddDeployJob(c *gin.Context) {
//	var flow cicd.DeploymentFlow
//	c.BindJSON(&flow)
//	flow.Create()
//	c.JSON(http.StatusOK,gin.H{
//		"code": 200,
//	})
//}
func AddDeployJob(c *gin.Context) {
	file,header,err := c.Request.FormFile("file")
	if err != nil { //测试报告
		c.String(http.StatusBadRequest,fmt.Sprintf("get file err : %s", err.Error()))
		return
	}


	workflow := cicd.DeploymentFlow{
		//Title: c.Request.Form['']
		Title: c.Request.Form.Get("title"),
		Content: c.Request.Form.Get("content"),
		OnlineTime: c.Request.Form.Get("onlinetime"),
		ItemList: c.Request.Form.Get("itemlist"),
		DbList: c.Request.Form.Get("dblist"),
		SqlList: c.Request.Form.Get("sqllist"),

		TestReportFilename: header.Filename,
		TestReportContent: file,

	}
	workflow.Create()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}


func GetDeployJobs(c *gin.Context) {
	var flow cicd.DeploymentFlow
	//c.BindJSON(&item)
	jobs,_ := flow.GetDeployJobs()

	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"jobs": jobs,
	})
}

func GetDeploymentJobStatus(c *gin.Context) {
	var flow cicd.DeploymentFlow
	//c.BindJSON(&item)
	flow.Id,_ = strconv.Atoi(c.Query("id"))

	status,_ := flow.GetDeployJobStatus()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
		"status": status,
	})
}


func BeginDeployJob(c *gin.Context) {
	var workflow cicd.DeploymentFlow
	c.BindJSON(&workflow)
	//job.Id,_ = strconv.Atoi(c.Query("id"))

	lock,_ := workflow.GetLock()
	if !lock {
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": fmt.Sprintf("该任务正在执行中，请稍后；任务ID：%d " , workflow.Id),
		})
		return
	}

	err := workflow.Start()
	if err != nil {
		fmt.Println("start deplayment status : " , err.Error())
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func CloseDeploymentJob(c *gin.Context) {
	var job models.DeplaymentJob
	job.Id,_ = strconv.Atoi(c.Query("id"))
	go job.Close()
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

//任务流中手动执行sql脚本
func BeginDeploySqlJobByHand(c *gin.Context) {
	var job models.SqlJob
	c.BindJSON(&job)
	fmt.Println("band sql job is " , job)

	go job.Run()  //可以异步，因为状态也是异步获取的
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}

func BeginDeployItemJobByHand(c *gin.Context) {
	var job models.DeplaymentItem
	//c.BindJSON(&job)
	//fmt.Println("band item job is " , job)
	id,_ := strconv.Atoi(c.Query("id"))
	job.Name = c.Query("name")
	go job.Run(id)
	//go job.Run()  //可以异步，因为状态也是异步获取的
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}


//删除部署任务
func DeleteDeployJob(c *gin.Context) {
	var workflow cicd.DeploymentFlow
	c.BindJSON(&workflow)
	err := workflow.Delete()
	if err != nil {
		c.JSON(http.StatusOK,gin.H{
			"code": 400,
			"message": err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK,gin.H{
		"code": 200,
	})
}



